package com.springboot.base.common;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.alibaba.fastjson.serializer.SerializerFeature;
import com.alibaba.fastjson.support.spring.FastJsonHttpMessageConverter;

import springfox.documentation.spring.web.json.Json;
import springfox.documentation.swagger.web.SecurityConfiguration;
import springfox.documentation.swagger.web.SwaggerResource;
import springfox.documentation.swagger.web.UiConfiguration;
import org.springframework.core.PriorityOrdered;
import org.springframework.http.HttpInputMessage;
import org.springframework.http.HttpOutputMessage;
import org.springframework.http.MediaType;
import org.springframework.http.converter.HttpMessageNotReadableException;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.charset.StandardCharsets;

/**
 * @author beike
 * @date 2021/03/18
 */
public class RequestBodyHttpMessageConverter extends FastJsonHttpMessageConverter implements PriorityOrdered {
    @Override
    public int getOrder() {
        return 0;
    }

    @Override
    protected boolean supports(Class<?> arg0) {
        return true;
    }


    @Override
    protected Object readInternal(Class<?> clazz, HttpInputMessage inputMessage) throws IOException, HttpMessageNotReadableException {
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        InputStream in = inputMessage.getBody();
        byte[] buf = new byte[1024];
        for (; ; ) {
            int len = in.read(buf);
            if (len == -1) {
                break;
            }
            if (len > 0) {
                byteArrayOutputStream.write(buf, 0, len);
            }
        }
        byte[] bytes = byteArrayOutputStream.toByteArray();
        try {
            return JSON.parseObject(bytes, 0, bytes.length, getCharset().newDecoder(), clazz);
        } catch (Exception e) {

        }
        if (clazz.equals(String.class)) {
            return new String(bytes);
        }
        return null;
    }

    @Override
    protected void writeInternal(Object o, HttpOutputMessage outputMessage)
            throws IOException {

        String stringResult;
        try {
            if (o instanceof Result || o instanceof UiConfiguration || o instanceof SwaggerResource || o instanceof SecurityConfiguration || o.toString().contains("SwaggerResource")) {
                //直接为Result类型、swagge类型, 不封装
                stringResult = JSON.toJSONString(o);
            } else if (o instanceof Json) {
                //Swagger支持: swagger接口返回SpringFox的Json  需要特殊处理
                stringResult = ((Json) o).value();

            } else if (o instanceof JSONObject) {
                //直接为JSONObject类型, 不封装
                stringResult = JSON.toJSONString(o);
            } else {
                stringResult = JSON.toJSONString(new Result(o), SerializerFeature.WriteDateUseDateFormat);
            }
        } catch (Exception e) {
            stringResult = "";
            logger.error("json转换异常 o:" + JSON.toJSONString(o));
        }
        byte[] payload = stringResult.getBytes(StandardCharsets.UTF_8);
        outputMessage.getHeaders().setContentType(MediaType.APPLICATION_JSON);
        outputMessage.getHeaders().setContentLength(payload.length);
        outputMessage.getBody().write(payload);
        outputMessage.getBody().flush();
    }

}
